當使用者登入系統後,無論是因為使用者權責亦或是為了系統安全,通常會建立適當的安全機制,除了密碼加密外,還有角色與權責分配,比如什麼樣的角色(role)分配什麼樣的功能。本節將帶大家透過 VoK-Security 建立系統權責劃分。
在本範例學生成績管理系統
裡,功能/角色分配如下 :
請打開 LoginServices.kt
data class User(
override var id: Long? = null,
var username: String = "",
override var hashedPassword: String = "",
var roles: String = ""
) : KEntity<Long>, HasPassword {
companion object : Dao<User, Long>(User::class.java) {
fun findByUsername(username: String): User? = findOneBy("username = :username") { query ->
query.bind("username", username)
}
}
}
VoK Secruity 提供hash加密password,無需自行轉換,只要實作 HasPassword
,並複寫 hashedPassword
,HasPassword
將會於設定密碼時,自動將加密後的 password 回寫 hashedPassword
在 web/src/main/resources/db/migration 下開新檔案 V03__CreateUser.sql
create table user (
id bigint auto_increment primary key not null,
username varchar(100) not null,
hashedPassword varchar(200) not null,
roles varchar(400) not null
);
create unique index on user(username);
除了primary key外,username
為唯一值,且將會根據username
查詢,所以建立唯一值索引 (unique index)
修改login()
fun login(username: String, password: String): Boolean {
//verify username and password
val user = User.findByUsername(username) ?: return false
if (!user.passwordMatches(password)) return false
currentUser = user
UI.getCurrent().page.reload()
return true
}
第三行,倘若無此使用者,回傳登入失敗 (false)
第四行,使用 HasPassword
提供的方法 passwordMatches()
檢查密碼
增加必要方法
fun getCurrentUserRoles(): Set<String>{
val roles: String = currentUser?.roles ?: return setOf()
return roles.split(",").toSet()
}
fun isUserInRole(role: String): Boolean = getCurrentUserRoles().contains(role)
fun isAdmin(): Boolean = isUserInRole("administrator")
第三行,一個使用者可具多重角色,各角色間以,
分隔
第六行,檢查role
是否存在
User(username = "admin", roles = "admin").apply { setPassword("admin") }.save(false)
User(username = "teacher", roles = "teacher").apply { setPassword("teacher") }.save(false)
User(username = "student", roles = "student").apply { setPassword("student") }.save(false)
HasPassword
所提供的方法 setPassword()
設定密碼.save(false)
表示儲存時不需檢查資料正確性。